package iso2.persistencia;

import java.sql.Connection;
import java.sql.SQLException;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

public class Agente {

	// Instancia del agente singleton
	private static Agente instancia;
	
	// Acceso a la base de datos MySQL
	private static MysqlDataSource bd;
	
	// Vector de conexiones
	private static Connection conexiones[];
	
	// Vector de disponibilidad de conexiones
	private static boolean dconexiones[];
	
	// Numero maximo de conexiones
	private static final int nconexiones = 10;
	
	// Datos de conexion con la BD
	private static final String	user = "iso2",
								password = "iso2",
								databaseName = "iso2",
								serverName = "localhost";
	
	// Inicialización 
	static {
		bd = new MysqlDataSource();
		conexiones = new Connection[nconexiones];
		dconexiones = new boolean[nconexiones];
		bd.setUser(user);
		bd.setPassword(password);
		bd.setDatabaseName(databaseName);
		bd.setServerName(serverName);
		for (int i = 0; i < nconexiones; i++) dconexiones[i] = true;
	}
	
	// Sobreescribir constructor singleton
	private Agente() { }
	
	// Metodo para obtener la instancia del agente
	public static Agente getInstancia() {
		if (instancia == null) instancia = new Agente();
		return instancia;
	}
	
	// Obtener una conexion con la base de datos
	public Connection getConexion() throws SQLException, 
										ConexionesOcupadasException {
		Connection conexion = null;
		
		// Buscar la primera conexion disponible y devolverla
		for (int i = 0; i < nconexiones && conexion == null; i++)
			
			// La conexion i esta disponible
			if (dconexiones[i]) {
				
				// Inicializar conexion i si no lo estaba
				if (conexiones[i] == null)
					conexiones[i] = bd.getConnection();

				conexion = conexiones[i];
				
				// Marcar conexion como no disponible
				dconexiones[i] = false;
			}
		
		// Si no hay ninguna conexion disponible, lanzar excepcion
		if (conexion == null)
			throw new ConexionesOcupadasException();
		
		// Devolver conexion disponible
		return conexion;
	}
	
	// Liberar una conexion
	public void liberarConexion(Connection conexion) {
		
		// Buscar la conexion liberada
		for (int i = 0; i < nconexiones; i++)
			if (conexiones[i] != null && conexiones[i].equals(conexion)) {
				
				// Marcar la conexion i como disponible
				dconexiones[i] = true;
				break;
			}
	}
	
	// Cerrar todas las conexiones
	public void cerrarConexiones() throws SQLException {
		for (int i = 0; i < nconexiones; i++) {
			if (conexiones[i] != null) conexiones[i].close();
			dconexiones[i] = true;
		}
	}
	
}
